# -*- coding: utf-8 -*-
"""
心理咨询师服务系统 - 量表模型
"""

from datetime import datetime
from sqlalchemy import Numeric
from app import db
from .base import BaseModel


class ScaleCategory(BaseModel):
    """量表分类表"""
    __tablename__ = 'scale_categories'
    
    name = db.Column(db.String(100), nullable=False, comment='分类名称')
    description = db.Column(db.Text, comment='分类描述')
    parent_id = db.Column(db.Integer, db.ForeignKey('scale_categories.id'), comment='父分类ID')
    sort_order = db.Column(db.Integer, default=0, comment='排序')
    icon = db.Column(db.String(100), comment='图标')
    color = db.Column(db.String(20), comment='颜色')
    status = db.Column(
        db.Enum('active', 'inactive', name='category_status'),
        default='active',
        comment='状态'
    )
    
    # 关系
    parent = db.relationship('ScaleCategory', remote_side='ScaleCategory.id', backref='children')
    scales = db.relationship('Scale', back_populates='category')
    
    def __repr__(self):
        return f'<ScaleCategory {self.name}>'


class ScalePublisher(BaseModel):
    """量表发布者关系表"""
    __tablename__ = 'scale_publishers'
    
    scale_id = db.Column(db.Integer, db.ForeignKey('scales.id'), nullable=False, comment='量表ID')
    publisher_type = db.Column(
        db.Enum('member', 'system', name='publisher_type'), 
        nullable=False, 
        comment='发布者类型'
    )
    publisher_id = db.Column(db.Integer, nullable=False, comment='发布者ID')
    publish_time = db.Column(db.DateTime, default=datetime.utcnow, comment='发布时间')
    status = db.Column(
        db.Enum('active', 'inactive', name='publisher_status'),
        default='active',
        comment='状态'
    )
    
    # 关系
    scale = db.relationship('Scale', back_populates='publishers')
    
    def __repr__(self):
        return f'<ScalePublisher {self.publisher_type}:{self.publisher_id}>'


class Scale(BaseModel):
    """量表主表"""
    __tablename__ = 'scales'
    
    title = db.Column(db.String(200), nullable=False, comment='量表标题')
    subtitle = db.Column(db.String(500), comment='量表副标题')
    description = db.Column(db.Text, comment='量表描述')
    instruction = db.Column(db.Text, comment='测试说明')
    category_id = db.Column(db.Integer, db.ForeignKey('scale_categories.id'), comment='分类ID')
    status = db.Column(
        db.Enum('DRAFT', 'PUBLISHED', 'ARCHIVED', name='scale_status'),
        default='DRAFT',
        comment='状态'
    )
    is_public = db.Column(db.Boolean, default=True, comment='是否公开')
    is_free = db.Column(db.Boolean, default=True, comment='是否免费')
    price = db.Column(db.Float, default=0.0, comment='价格')
    question_count = db.Column(db.Integer, default=0, comment='题目数量')
    estimated_time = db.Column(db.Integer, comment='预估完成时间(分钟)')
    usage_count = db.Column(db.Integer, default=0, comment='使用次数')
    version = db.Column(db.String(20), default='1.0', comment='版本号')
    author = db.Column(db.String(100), comment='作者')
    copyright_info = db.Column(db.Text, comment='版权信息')
    published_at = db.Column(db.DateTime, comment='发布时间')
    min_member_level = db.Column(
        db.Enum('basic', 'professional', 'institution', 'research', name='member_level'),
        default='basic',
        comment='使用该量表所需的最低会员级别'
    )
    
    # 关系
    category = db.relationship('ScaleCategory', back_populates='scales')
    publishers = db.relationship('ScalePublisher', back_populates='scale', cascade='all, delete-orphan')
    questions = db.relationship('ScaleQuestion', back_populates='scale', cascade='all, delete-orphan')
    scoring_rules = db.relationship('ScaleScoringRule', back_populates='scale', cascade='all, delete-orphan')
    tags = db.relationship('ScaleTag', back_populates='scale', cascade='all, delete-orphan')
    assessments = db.relationship('Assessment', back_populates='scale', lazy='dynamic')
    
    def get_publisher(self):
        """获取主要发布者信息"""
        if self.publishers:
            return self.publishers[0]
        return None
    
    def is_published_by_member(self, user_id):
        """检查是否由指定会员发布"""
        for publisher in self.publishers:
            if publisher.publisher_type == 'member' and publisher.publisher_id == user_id:
                return True
        return False
    
    def can_edit(self, user_id, user_type='member'):
        """检查是否可以编辑"""
        from flask import current_app
        
        if user_type == 'admin':
            return True
        
        # 调试信息 - 使用print确保能看到
        print(f'[DEBUG] 检查用户 {user_id} 对量表 {self.id} 的编辑权限')
        print(f'[DEBUG] 量表发布者数量: {len(self.publishers) if self.publishers else 0}')
        print(f'[DEBUG] 是否为系统内置量表: {self.is_system_scale()}')
        
        # 如果没有发布者记录，允许任何会员编辑
        if not self.publishers:
            print(f'[DEBUG] 量表 {self.id} 没有发布者记录，允许用户 {user_id} 编辑')
            return True
        
        # 如果是系统内置量表，允许任何会员发布（这是会员发布系统量表的核心功能）
        if self.is_system_scale():
            print(f'[DEBUG] 量表 {self.id} 是系统内置量表，允许用户 {user_id} 发布')
            return True
            
        # 对于会员创建的量表，只有创建者可以编辑
        result = self.is_published_by_member(user_id)
        print(f'[DEBUG] 用户 {user_id} 是否为量表 {self.id} 的发布者: {result}')
        return result
    
    def can_use(self, user_membership_level):
        """检查会员是否可以使用该量表"""
        if not self.min_member_level:
            return True
        
        # 定义会员级别优先级
        level_priority = {
            'basic': 1,
            'professional': 2, 
            'institution': 3,
            'research': 4
        }
        
        user_priority = level_priority.get(user_membership_level, 0)
        required_priority = level_priority.get(self.min_member_level, 1)
        
        return user_priority >= required_priority
    
    def is_system_scale(self):
        """检查是否为系统内置量表"""
        for publisher in self.publishers:
            if publisher.publisher_type == 'system':
                return True
        return False
    
    def get_creator_info(self):
        """获取创建者信息"""
        if self.publishers:
            publisher = self.publishers[0]
            if publisher.publisher_type == 'system':
                return {'type': 'system', 'name': '系统内置'}
            else:
                # 获取会员信息
                from .user import User
                user = User.query.get(publisher.publisher_id)
                if user:
                    # 优先使用用户名，如果为空则使用邮箱，如果都为空则使用用户ID
                    display_name = user.username or user.email or f'用户{user.id}'
                    return {'type': 'member', 'name': display_name}
                else:
                    # 用户不存在时显示发布者ID
                    return {'type': 'member', 'name': f'会员{publisher.publisher_id}'}
        return {'type': 'unknown', 'name': '未知'}
    
    def __repr__(self):
        return f'<Scale {self.title}>'


class ScaleQuestion(BaseModel):
    """量表题目表"""
    __tablename__ = 'scale_questions'
    
    scale_id = db.Column(db.Integer, db.ForeignKey('scales.id'), nullable=False, comment='量表ID')
    question_number = db.Column(db.Integer, nullable=False, comment='题目序号')
    question_text = db.Column(db.Text, nullable=False, comment='题目内容')
    question_type = db.Column(
        db.Enum('single', 'multiple', 'text', 'scale', 'boolean', name='question_type'),
        nullable=False,
        comment='题目类型'
    )
    is_required = db.Column(db.Boolean, default=True, comment='是否必答')
    
    # 表约束
    __table_args__ = (
        db.UniqueConstraint('scale_id', 'question_number', name='uk_scale_question'),
    )
    
    # 关系
    scale = db.relationship('Scale', back_populates='questions')
    options = db.relationship('QuestionOption', back_populates='question', cascade='all, delete-orphan')
    
    def __repr__(self):
        return f'<ScaleQuestion {self.question_number}: {self.question_text[:50]}>'


class QuestionOption(BaseModel):
    """题目选项表"""
    __tablename__ = 'question_options'
    
    question_id = db.Column(db.Integer, db.ForeignKey('scale_questions.id'), nullable=False, comment='题目ID')
    option_key = db.Column(db.String(10), nullable=False, comment='选项标识')
    option_text = db.Column(db.String(500), nullable=False, comment='选项内容')
    option_value = db.Column(db.Integer, comment='选项分值')
    sort_order = db.Column(db.Integer, default=0, comment='排序')
    
    # 表约束
    __table_args__ = (
        db.UniqueConstraint('question_id', 'option_key', name='uk_question_option'),
    )
    
    # 关系
    question = db.relationship('ScaleQuestion', back_populates='options')
    
    def __repr__(self):
        return f'<QuestionOption {self.option_key}: {self.option_text}>'


class ScaleScoringRule(BaseModel):
    """量表计分规则表"""
    __tablename__ = 'scale_scoring_rules'
    
    scale_id = db.Column(db.Integer, db.ForeignKey('scales.id'), nullable=False, comment='量表ID')
    rule_name = db.Column(db.String(100), nullable=False, comment='规则名称')
    rule_type = db.Column(
        db.Enum('total', 'dimension', 'level', name='scoring_rule_type'),
        nullable=False,
        comment='规则类型'
    )
    calculation_method = db.Column(
        db.Enum('sum', 'average', 'weighted', 'custom', name='calculation_method'),
        nullable=False,
        comment='计算方法'
    )
    min_score = db.Column(Numeric(10, 2), comment='最低分')
    max_score = db.Column(Numeric(10, 2), comment='最高分')
    weight = db.Column(Numeric(5, 2), default=1.00, comment='权重')
    formula = db.Column(db.Text, comment='计算公式')
    
    # 关系
    scale = db.relationship('Scale', back_populates='scoring_rules')
    dimensions = db.relationship('ScoringRuleDimension', back_populates='scoring_rule', cascade='all, delete-orphan')
    
    def __repr__(self):
        return f'<ScaleScoringRule {self.rule_name}>'


class ScoringRuleDimension(BaseModel):
    """计分规则维度表"""
    __tablename__ = 'scoring_rule_dimensions'
    
    # 覆盖BaseModel的updated_at字段，因为数据库表中没有这个字段
    updated_at = None
    
    rule_id = db.Column(db.Integer, db.ForeignKey('scale_scoring_rules.id'), nullable=False, comment='规则ID')
    dimension_name = db.Column(db.String(100), nullable=False, comment='维度名称')
    question_numbers = db.Column(db.Text, nullable=False, comment='题目序号列表(逗号分隔)')
    weight = db.Column(Numeric(5, 2), default=1.00, comment='维度权重')
    
    # 关系
    scoring_rule = db.relationship('ScaleScoringRule', back_populates='dimensions')
    
    def __repr__(self):
        return f'<ScoringRuleDimension {self.dimension_name}>'


class ScaleTag(BaseModel):
    """量表标签表"""
    __tablename__ = 'scale_tags'
    
    # 覆盖BaseModel的updated_at字段，因为数据库表中没有这个字段
    updated_at = None
    
    scale_id = db.Column(db.Integer, db.ForeignKey('scales.id'), nullable=False, comment='量表ID')
    tag_name = db.Column(db.String(50), nullable=False, comment='标签名称')
    tag_color = db.Column(db.String(20), comment='标签颜色')
    
    # 表约束
    __table_args__ = (
        db.UniqueConstraint('scale_id', 'tag_name', name='uk_scale_tag'),
    )
    
    # 关系
    scale = db.relationship('Scale', back_populates='tags')
    
    def __repr__(self):
        return f'<ScaleTag {self.tag_name}>'


class MemberScalePublication(BaseModel):
    """会员量表发布表"""
    __tablename__ = 'member_scale_publications'
    
    member_id = db.Column(db.Integer, db.ForeignKey('users.id'), nullable=False, comment='会员ID')
    scale_id = db.Column(db.Integer, db.ForeignKey('scales.id'), nullable=False, comment='量表ID')
    publication_token = db.Column(db.String(64), nullable=False, unique=True, comment='发布令牌')
    custom_title = db.Column(db.String(200), comment='自定义标题')
    custom_description = db.Column(db.Text, comment='自定义描述')
    is_active = db.Column(db.Boolean, default=True, comment='是否激活')
    access_count = db.Column(db.Integer, default=0, comment='访问次数')
    assessment_count = db.Column(db.Integer, default=0, comment='测评次数')
    last_accessed_at = db.Column(db.DateTime, comment='最后访问时间')
    
    # 表约束
    __table_args__ = (
        db.UniqueConstraint('member_id', 'scale_id', name='uk_member_scale'),
    )
    
    # 关系
    member = db.relationship('User', backref='scale_publications')
    scale = db.relationship('Scale', backref='member_publications')
    assessments = db.relationship('Assessment', back_populates='publication')
    
    def generate_public_url(self, base_url):
        """生成公开访问URL"""
        return f"{base_url}/public/scale/{self.publication_token}"
    
    def increment_access_count(self):
        """增加访问次数"""
        self.access_count += 1
        self.last_accessed_at = datetime.utcnow()
        db.session.commit()
    
    def increment_assessment_count(self):
        """增加测评次数"""
        self.assessment_count += 1
        db.session.commit()
    
    @staticmethod
    def generate_token():
        """生成唯一令牌"""
        import secrets
        return secrets.token_urlsafe(48)  # 生成64字符的URL安全令牌
    
    def __repr__(self):
        return f'<MemberScalePublication {self.member_id}:{self.scale_id}>'
